/**
 * PageMarket
 * ContentManager.java
 * com.android.pagemarket.business.logic
 * 
 */
package com.android.pagemarket.business.logic;

import java.sql.SQLException;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Date;
import java.util.List;
import java.util.concurrent.atomic.AtomicInteger;

import android.os.AsyncTask;
import android.os.Handler;
import android.text.TextUtils;
import android.util.Log;

import com.android.pagemarket.MyApplication;
import com.android.pagemarket.business.model.Message;
import com.android.pagemarket.io.database.DB;
import com.android.pagemarket.io.protocol.HttpManager;
import com.android.pagemarket.io.protocol.in.HttpAction.ActionListener;
import com.android.pagemarket.io.protocol.in.MessageAction;
import com.android.pagemarket.io.protocol.in.PushAction;
import com.android.pagemarket.io.protocol.out.MessageList;
import com.android.pagemarket.io.protocol.out.PushResult;
import com.android.pagemarket.ui.service.PushService;
import com.android.pagemarket.util.CycledThread;
import com.android.pagemarket.util.MyNotificationManager;
import com.android.pagemarket.util.NotifyListener;
import com.j256.ormlite.dao.Dao;
import com.j256.ormlite.stmt.DeleteBuilder;
import com.j256.ormlite.stmt.QueryBuilder;

/*********************************************************
 * @author : zhaohua
 * @version : 2012-11-7
 * @see : 内容管理器
 * @Copyright : copyrights reserved by personal 2007-2012
 **********************************************************/
public class ContentManager extends BaseManager
{
    private static final String TAG = "ContentManager";
    private Dao<Message, Integer> mMessageDao;
    private CycledThread          mPushThread;
    private Thread                mPushOnceThread;
    private ArrayList<Integer> alertReadMap = new ArrayList<Integer>();
    private ArrayList<Integer> promoReadMap = new ArrayList<Integer>();    
    private Handler mHandler;
    // 未读数
    private int unreadAlert = 0;
    private int unreadPromo = 0;
    ////////////////////////////////////////////////////////////////
    private ContentManager()
    {
        mMessageDao = DB.getDatabaseHelper().getMessageDao();
    }
    private static ContentManager instance;
    public static ContentManager getInstance()
    {
        if(instance == null)
        {
            instance = new ContentManager();
        }
        return instance;
    }
    @Override
    public void init()
    {        
        if(MyApplication.getContext().isPushOn())
        {
            startPush();
        }
        restoreReadedList(); 
    }

    @Override
    public void destory()
    {
        stopPush();
    }
    ////////////////////////////////////////////////////////////////
    // 获取消息列表
    public void getMessageList(final int type, final int maxNo, final int pageNum,
            final NotifyListener<List<Message>> listener)
    {
        
        MessageAction action = null;
        action = new MessageAction(maxNo, 10, type);
        
        action.setActionListener(new ActionListener<MessageList>()
        {
            @Override
            public void onSucceed(MessageList result)
            {
                if(result.isNoError())
                {
                    if(result.list != null && result.list.size() > 0)
                    {
                          updateReadedList(result.list);
                          listener.onSucceed(result.list);
                    }else
                    {
                          listener.onSucceed(result.list);
                    }
                }else
                {
                        listener.onSucceed(result.list);
                }
            }
            @Override
            public void onError(int resultCode)
            {
                listener.onError(resultCode);
            }
        });
        HttpManager.getInstance().submitAction(action);
    }
    
    // 获取缓存快讯列表
    void getMessageListByDB(final int type, final int page, final int pageNum, final NotifyListener<List<Message>> listener)
    {
        new AsyncTask<Void, Void, List<Message>>()
        {
            @Override
            protected List<Message> doInBackground(Void... params)
            {
                QueryBuilder<Message, Integer> subQueryBuilder = mMessageDao.queryBuilder();
                try
                {
                    subQueryBuilder.orderBy("no", false);
                    subQueryBuilder.where().eq("type", type);
                    if(page >= 0 && pageNum > 0)
                    {
                        subQueryBuilder.offset((long)page*pageNum);
                        subQueryBuilder.limit((long)pageNum);
                    }
                    return mMessageDao.query(subQueryBuilder.prepare());
                } catch (SQLException e)
                {
                    e.printStackTrace();
                }
                return null;
            }
            protected void onPostExecute(List<Message> result) 
            {
                listener.onSucceed(result);
            };
        }.execute();
    }
    
    // 更新消息列表的已读信息
    public void updateReadedList(List<Message> list)
    {        
        if(list != null && list.size() > 0)
        {
            int maxNo = 0;
            int type = 0;
            
            for(Message msg : list)
            {
                type = msg.type;
                if(msg.type == Message.TYPE_ALERTS)
                {
                    if(alertReadMap.contains(msg.no))
                    {
                        msg.isRead = true;
                    }else
                    {
                        msg.isRead = false;                        
                    }
                }else
                {
                    if(promoReadMap.contains(msg.no))
                    {
                        msg.isRead = true;
                    }else
                    {
                        msg.isRead = false;
                    }
                }
                if(maxNo < msg.no)
                {
                    maxNo = msg.no;
                }
            }
            if(type == Message.TYPE_ALERTS)
            {
                InitManager.getInstance().updateAlertVersion(maxNo);
            }else
            {
                InitManager.getInstance().updatePromotVersion(maxNo);
            }
        }
    }
    
    /** 恢复已读列表映射*/
    private void restoreReadedList()
    {
        new AsyncTask<Void, Void, Void>()
        {
            @Override
            protected Void doInBackground(Void... params)
            {                
                try
                {
                    List<Message> list = mMessageDao.queryForAll();
                    if(list != null && list.size() > 0)
                    {
                        for(Message msg : list)
                        {
                            if(msg.type == Message.TYPE_ALERTS)
                            {
                                alertReadMap.add(msg.no);
                            }else
                            {
                                promoReadMap.add(msg.no);
                            }
                        }
                    }
                } catch (SQLException e)
                {
                    e.printStackTrace();
                }
                return null;
            }
        }.execute();
    }
    
    // 更新快讯列表到数据库
    void updateMessageList(final List<Message> list)
    {
        if(list == null || list.size() ==0) return;
        new AsyncTask<Void, Void, Void>()
        {
            @Override
            protected Void doInBackground(Void... params)
            {
                // 保存到数据库
                int type = 0;
                int maxNo = 0;
                int size = list.size();
                
                for(int i = 0; i < size; i++)
                {                   
                    try
                    {
                        Message msg = list.get(i);
                        type = msg.type;                        
                        mMessageDao.create(msg);
                        if(i == size-1)
                        {
                            maxNo = msg.no;
                        }
                    } catch (SQLException e)
                    {
                        e.printStackTrace();
                    }
                }
                if(type == Message.TYPE_ALERTS)
                {
                    InitManager.getInstance().updateAlertVersion(maxNo);
                }else
                {
                    InitManager.getInstance().updatePromotVersion(maxNo);
                }
                // 获取总条数
                long total = 0;
                try
                {
                    total = mMessageDao.countOf();
                } catch (SQLException e1)
                {
                    e1.printStackTrace();
                }
                if(total < 30)
                {
                    // 小于30条则不处理
                    return null;
                }
                // 只保留最新的30条
                DeleteBuilder<Message, Integer> builder = mMessageDao.deleteBuilder();
                QueryBuilder<Message, Integer> subQueryBuilder = mMessageDao.queryBuilder();
                subQueryBuilder.selectColumns("no");
                
                try
                {
                    subQueryBuilder.orderBy("no", false);
                    subQueryBuilder.where().eq("type", type);
                    subQueryBuilder.offset((long)30);
                    subQueryBuilder.limit((long)100);
                    builder.where().in("no", subQueryBuilder);
                    
                    mMessageDao.delete(builder.prepare());                                       
                } catch (SQLException e)
                {
                    e.printStackTrace();
                }
                return null;
            }
        }.execute();
    }    

    // 将这个消息更新为已读
    public void updateRead(final Message msg)
    {
        new AsyncTask<Void, Void, Void>()
        {
            @Override
            protected Void doInBackground(Void... params)
            {
                msg.isRead = true;
                try
                {
                    mMessageDao.createOrUpdate(msg);
                    if(msg.type == Message.TYPE_ALERTS)
                    {
                        alertReadMap.add(msg.no);
                    }else
                    {
                        promoReadMap.add(msg.no);
                    }
                } catch (SQLException e)
                {
                    e.printStackTrace();
                }
                return null;
            }
        }.execute();
    }
    
    // 更新未读数目
    public void updateUnread(List<Message> list, int type)
    {
        if(list == null || list.size() == 0)
        {
            if(type == Message.TYPE_ALERTS)
            {
                unreadAlert = 0;
            }else
            {
                unreadPromo = 0;
            }
        }else
        {
            int unread = 0;
            for(Message one : list)
            {
                if(!one.isRead)
                {
                    unread++;
                }
            }
            if(type == Message.TYPE_ALERTS)
            {
                unreadAlert = unread;
            }else
            {
                unreadPromo = unread;
            }
        }
        sendUnreadMsg();
    }
    
    public void sendUnreadMsg()
    {
        if(mHandler == null) return;
        int unread = unreadAlert + unreadPromo;
        android.os.Message msg = mHandler.obtainMessage();
        msg.what = 0x12345678;
        msg.arg1 = unread;
        mHandler.sendMessage(msg);
    }
    
    public void setUnreadHandler(Handler handler)
    {
        mHandler = handler;
    }
    
    // 获取快讯的头条
    void getHeadMessage(final NotifyListener<Message> listener)
    {
        new AsyncTask<Void, Void, Message>()
        {
            @Override
            protected Message doInBackground(Void... params)
            {
                QueryBuilder<Message, Integer> subQueryBuilder = mMessageDao.queryBuilder();
                try
                {
                    subQueryBuilder.orderBy("no", false);
                    subQueryBuilder.where().eq("type", Message.TYPE_ALERTS);
                    subQueryBuilder.offset((long)0);
                    subQueryBuilder.limit((long)1);
                    
                    List<Message> list = mMessageDao.query(subQueryBuilder.prepare());
                    if(list != null && list.size() > 0)
                    {
                        return list.get(0);
                    }
                } catch (SQLException e)
                {
                    e.printStackTrace();
                }
                return null;
            }
            protected void onPostExecute(Message result) 
            {
                listener.onSucceed(result);
            };
        }.execute();
    }
    
    // 开始进行轮询获取
    private AtomicInteger mLoopCount = new AtomicInteger(0);
    public void startPush()
    {
        if(!InitManager.getInstance().isInitOK())
        {
            InitManager.getInstance().doInit(null);
            return;
        }
        // 只有初始化成功后，才能进行下步操作
        if(mPushThread == null)
        {
            mLoopCount.set(0);
            mPushThread = new CycledThread(new Runnable()
            {
                @Override
                public void run()
                {
                    doPush(false);
                }
            }, 28*60*1000);
            mPushThread.start();
            PushService.startService();
        }
    }
    
    // 只推送一次
    public void startPushOnce()
    {
        if(!InitManager.getInstance().isInitOK())
        {
            InitManager.getInstance().doInit(new NotifyListener<Boolean>()
            {
                @Override
                public void onSucceed(Boolean result)
                {
                    doPushAsyn();
                }
                @Override
                public void onError(int resultCode)
                {
                    Log.e(TAG, "-->init Error!");
                }
            });
        }else 
        {
            doPushAsyn();
        }
    }
    
    private void doPushAsyn()
    {
        Log.d(TAG, "---> doPushAsyn");
        if(mPushOnceThread == null)
        {
            mPushOnceThread = new Thread(new Runnable()
            {
                @Override
                public void run()
                {
                    doPush(true);
                    mPushOnceThread = null;
                }
            });
            mPushOnceThread.start();
        }
    }
    
    private void doPush(boolean onceable)
    {
        // 获取快讯与促销的最新消息
        if(MyApplication.getContext().isPushOn(true, false, false))
        {
            // 当重新一次扫描 或者 一个小时之后 执行一次
            if(onceable || mLoopCount.get()%2 == 0)
            {
                MessageAction action = null;
                int type = 0;
                for(int i=0; i < 2; i++)
                {
                    if(i == 0) type = Message.TYPE_ALERTS;
                    else       type = Message.TYPE_PROMOT;
                    
                    if(type == Message.TYPE_ALERTS)
                    {
                        action = new MessageAction(InitManager.getInstance().getAlertVersion(),10, Message.TYPE_ALERTS);
                    }else
                    {
                        action = new MessageAction(InitManager.getInstance().getPromotVersion(),10, Message.TYPE_PROMOT);
                    }
                    action.setActionListener(new ActionListener<MessageList>()
                    {
                        @Override
                        public void onSucceed(MessageList result)
                        {
                            if(result.isNoError())
                            {
                                if(result.list != null && result.list.size() > 0)
                                {
                                    // 更新
                                    updateReadedList(result.list);
                                    // 发通知到通知栏
                                    MyNotificationManager.showMsgInNotification(MyApplication.getContext(), result.list);
                                }else
                                {
                                    Log.d(TAG, "-->push no result!");
                                }
                            }else
                            {
                                Log.d(TAG, "-->push no result :" + result.resultInfo);
                            }
                        }
                        @Override
                        public void onError(int resultCode)
                        {
                            Log.d(TAG, "-->push error :" + MessageAction.getErrorMean(resultCode));
                        }
                    });
                    HttpManager.getInstance().submitAction(action);
                    
                    if(i == 0)
                    {
                        try
                        {
                            Thread.sleep(5000);
                        } catch (InterruptedException e)
                        {
                            e.printStackTrace();
                        }
                    }
                }
            }
        }
        
        // 其他推送
        String pushUrl = InitManager.getInstance().getPushUrl();
        if(pushUrl != null && InitManager.getInstance().isLogin())
        {
            PushAction pushAction1 = null;
            PushAction pushAction2 = null;            
            // 出厂更新 半个小时 实时更新
            if(MyApplication.getContext().isPushOn(false, true, false))
            {
                pushAction1 = new PushAction(pushUrl, 
                        InitManager.getInstance().mLoginCompany.companyNum);
                pushAction1.setDateTime(null,InitManager.getInstance().getLastLeaveTime());
            }
            // 报价更新 1个小时 一天一次
            if(MyApplication.getContext().isPushOn(false, false, true))
            {
                pushAction2 = new PushAction(pushUrl, 
                        InitManager.getInstance().mLoginCompany.companyNum);
                pushAction2.setDateTime(InitManager.getInstance().getLastQutoDateTime(),null);                
                if(!onceable && mLoopCount.get()%2 == 0)
                {
                    // 时间检测
                    Calendar cal = Calendar.getInstance();
                    int hour = cal.get(Calendar.HOUR_OF_DAY);
                    // 非一次，在 0点 和 早上 8点
                    if(hour != 0 && hour != 8)
                    {
                        pushAction2 = null;
                    }
                }
                if(MyApplication.getContext().isQuotPushed()) 
                {
                    pushAction2 = null;
                }
            }
            if(pushAction1 != null || pushAction2 != null)
            {
                ActionListener<PushResult> listener = new ActionListener<PushResult>()
                {
                    @Override
                    public void onSucceed(PushResult result)
                    {
                        if(result.isNoError())
                        {
                            if(!TextUtils.isEmpty(result.leaveMsg))
                            {
                                MyNotificationManager.showMsgInNotification(MyApplication.getContext(), false, result.leaveMsg);
                                InitManager.getInstance().updateLastLeaveTime(System.currentTimeMillis());
//                                MyApplication.getContext().setOrderPushRecord(InitManager.formater.format(new Date()));
                            }
                            if(!TextUtils.isEmpty(result.qutoMsg))
                            {
                                MyNotificationManager.showMsgInNotification(MyApplication.getContext(), true, result.qutoMsg);
                                InitManager.getInstance().updateLastQutoDateTime(System.currentTimeMillis());
                                MyApplication.getContext().setQuotPushRecord(InitManager.formater.format(new Date()));
                            }
                            Log.e(TAG, "-->PushAction OK");
                        }else
                        {
                            Log.e(TAG, "-->PushAction" + result.resultInfo);
                        }
                    }
                    @Override
                    public void onError(int resultCode)
                    {
                        Log.e(TAG, "-->PushAction" + PushAction.getErrorMean(resultCode));
                    }
                };
                
                if(pushAction1 != null)
                {
                    pushAction1.setActionListener(listener);
                    pushAction1.submit();
                }
                if(pushAction2 != null) 
                {
                    if(pushAction1 != null)
                    {
                        try
                        {
                            Thread.sleep(5000);
                        } catch (InterruptedException e)
                        {
                            e.printStackTrace();
                        }
                    }                               
                    pushAction2.setActionListener(listener);
                    pushAction2.submit();
                }               
            }
        }      
        // 非一次性条件下，增1
        if(!onceable)
        {
            mLoopCount.incrementAndGet();
        }
    }
    
    // 停止进行轮询获取
    public void stopPush()
    {
        if(mPushThread != null)
        {
            mPushThread._stop();
            mPushThread = null;
            PushService.stotService();
        }
    }
}